home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / drdobbs.zip / WHTITLES.C < prev    next >
C/C++ Source or Header  |  1993-08-04  |  3KB  |  103 lines

  1. /* 
  2. WHTITLES.C -- dump titles from Windows .HLP or .MVB file
  3. Pete Davis and Andrew Schulman, September 1993
  4. From Dr. Dobb's Journal, October 1993
  5.  
  6. bcc -DDO_TITLES whtitles.c helpdir.c
  7. */
  8.  
  9. #pragma pack(1)
  10. #include <conio.h>
  11. #include <string.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include "whstruct.h"
  15.  
  16. extern void fail(const char *s);
  17.  
  18. #define GET_STRING(f, s) { char *p = (s); while (*p++ = fgetc(f)) ; *p = 0; }
  19.  
  20. #define PAGE_SIZE       1024L        /* 1k pages for WHIFS B-Tree */
  21. #define TTLPAGE_SIZE    2048L        /* 2k pages for TTLBTREE     */
  22.  
  23. int GetFirstLeaf(FILE *HelpFile, long FirstPageLoc, int LeafLevel) {
  24.    int              CurrLevel = 1, NextPage = 0;
  25.    BTREEINDEXHEADER CurrNode;
  26.  
  27.    while (CurrLevel < LeafLevel) {
  28.      fread(&CurrNode, 4, 1, HelpFile);
  29.      fread(&NextPage, sizeof(int), 1, HelpFile);
  30.      GotoPage(NextPage);
  31.      CurrLevel++;
  32.    }
  33.    return NextPage;
  34. }
  35.  
  36. long find_whifs_file(FILE *HelpFile, long WHIFSStart, char *name)
  37. {
  38.    BTREENODEHEADER    WHIFSNode;
  39.    long FileOffset;
  40.    char filename[20];
  41.    int file;
  42.    
  43.    do {
  44.        fread(&WHIFSNode, sizeof(WHIFSNode), 1, HelpFile);
  45.     
  46.        /* Search all entries in node */
  47.        for (file = 1; file <= WHIFSNode.NEntries; file ++) {
  48.           GET_STRING(HelpFile, filename);
  49.           fread(&FileOffset, sizeof(FileOffset), 1, HelpFile);
  50.           if (strcmp(filename, name) == 0)
  51.               return FileOffset;
  52.        }
  53.        if (WHIFSNode.NextPage != -1)
  54.           fseek(HelpFile, WHIFSStart + (WHIFSNode.NextPage * PAGE_SIZE), 
  55.               SEEK_SET);
  56.    } while (WHIFSNode.NextPage != -1);
  57.    return 0L;    // can't find
  58. }
  59.  
  60. void do_titles(FILE *HelpFile, long WHIFSStart)
  61. {
  62.    BTREEHEADER        BTreeHdr;
  63.    BTREENODEHEADER  CurrNode;
  64.    FILEHEADER        FileHdr;
  65.    long                FirstPageLoc, CurrPage;
  66.    unsigned long    TopicOffset;
  67.    long                TTLBTreeOffset=0, FileStart;
  68.    char                Title[80], *data;
  69.    int                file, txt, count, *Offsets;
  70.  
  71.    if (! (TTLBTreeOffset=find_whifs_file(HelpFile, WHIFSStart, "|TTLBTREE")))
  72.        fail("Can't locate |TTLBTREE file");
  73.     
  74.    /* Get TTLBTREE header */
  75.    fseek(HelpFile, TTLBTreeOffset, SEEK_SET);
  76.    fread(&FileHdr, sizeof(FileHdr), 1, HelpFile);
  77.    fread(&BTreeHdr, sizeof(BTreeHdr), 1, HelpFile);
  78.    FirstPageLoc = ftell(HelpFile);
  79.    GotoPage(BTreeHdr.RootPage);
  80.  
  81.    printf("%lu titles in |TTLBTREE:\n\n", BTreeHdr.TotalBtreeEntries);
  82.    CurrPage = GetFirstLeaf(HelpFile, FirstPageLoc, BTreeHdr.NLevels);
  83.    
  84.    do {
  85.      GotoPage(CurrPage);
  86.      fread(&CurrNode, 8, 1, HelpFile);
  87.      for(count = 1; count <= CurrNode.NEntries; count++) {
  88.         fread(&TopicOffset, sizeof(TopicOffset), 1, HelpFile);
  89.           GET_STRING(HelpFile, Title);
  90.         if (*Title) 
  91.         {
  92.             printf("0x%05lX/0x%04X\t%s\n",
  93.                 TopicOffset >> 15L,        // block number = upper 17 bits
  94.                 (unsigned short) TopicOffset & 0x8FFF,    // char offset
  95.                 Title);
  96.         }
  97.      }
  98.      CurrPage = CurrNode.NextPage;
  99.    } while(CurrPage != -1);
  100. }
  101.  
  102.  
  103.